<template>
    <button @click="initCamera">初始化摄像头</button>&nbsp;
    <button @click="scanner">扫码</button>&nbsp;
    <button @click="close">关闭</button>&nbsp;
    <div class="container">
        <video id="video"></video>
        <div v-if="mask" class="mask"></div>
    </div>
    <input type="file" @change="fileChange" accept="image/*">
    <h4>识别到的信息：<span style="color: red;">{{ message }}</span></h4>
</template>

<script setup>
import { ref } from "vue";
import { BrowserMultiFormatReader } from '@zxing/library';

let message = ref('');
let codeReader = null;
let selectedDeviceId = '';
let mask = ref(false);

async function initCamera() {
    if (!selectedDeviceId) {
        // 识别和处理多种常见的条形码和二维码格式
        codeReader = new BrowserMultiFormatReader();
        // 获取当前设备上可用的视频输入设备列表
        const videoInputDevices = await codeReader.getVideoInputDevices()
        if (!videoInputDevices.length) {
            return alert('没有找到可用的摄像头');
        }
        alert(JSON.stringify(videoInputDevices))
        if (videoInputDevices.length > 1) {
            // 后缀摄像头（手机）
            selectedDeviceId = videoInputDevices[1].deviceId;
        } else {
            // 前置摄像头
            selectedDeviceId = videoInputDevices[0].deviceId;
        }
    }
}

async function scanner() {
    await initCamera();
    if (!selectedDeviceId) { return }
    mask.value = true
    // 自动打开指定的视频输入设备，并实时对视频流中的每一帧图像进行条形码和二维码的解码操作，此方法不是只进行一次解码尝试，而是在视频流持续传输的过程中，不断地对每一帧图像进行解码分析
    codeReader.decodeFromVideoDevice(selectedDeviceId, 'video', (result, err) => {
        if (result) {
            message.value = result.text;
        }
        if (err) {
            console.error(err);
        }
    })
}
function close() {
    codeReader.reset();
    message.value = '';
    mask.value = false;
}

function fileChange(event) {
    const file = event.target.files[0];
    const reader = new FileReader();
    reader.onload = (e) => {
        const img = new Image();
        img.onload = () => {
            const barcodeReader = new BrowserMultiFormatReader();
            // 从图像元素中解码二维码或条形码
            barcodeReader.decodeFromImage(img)
                .then(result => {
                    message.value = result.text;
                })
                .catch(err => {
                    console.error(err);
                });
        };
        img.src = e.target.result;
    };
    reader.readAsDataURL(file);
}



</script>

<style>
.container {
    width: 100%;
    height: 45vh;
    position: relative;
    margin-top: 10px;
    overflow: hidden;
}

.container>video {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.mask {
    position: absolute;
    left: 15%;
    top: 20%;
    max-width: 100%;
    width: 70%;
    height: 60%;
    border-radius: 2px;
    outline: rgba(0, 0, 0, .25) solid 20vmax;
}
</style>
